package wechat

import (
	"crypto/hmac"
	"crypto/md5"
	"crypto/sha256"
	"encoding/hex"
	"fmt"
	"sort"
	"strings"
)

// SignType 签名类型
type SignType string

// SignType
const (
	SignTypeMd5        SignType = "MD5"
	SignTypeHMACSHA256 SignType = "HMAC-SHA256"
)

// SortedMapToString 对map进行排序
// param: wechat请求参数map
// appKey: 微信appKey
// return: 拼接好的字符串
func SortedMapToString(param map[string]any,
	appKey string) string {
	if param == nil {
		return ""
	}
	keys := make([]string, 0, len(param))
	for key := range param {
		keys = append(keys, key)
	}
	sort.Strings(keys)
	var build strings.Builder
	for i, v := range keys {
		build.WriteString(v)
		build.WriteString("=")
		build.WriteString(fmt.Sprintf("%v", param[v]))
		if i != len(keys)-1 {
			build.WriteString("&")
		}
	}
	build.WriteString(fmt.Sprintf("&key=%s", appKey))
	return build.String()
}

// CreateWechatHmacSha256 创建微信签名
// plainText: 待签名字符串
// appKey: 微信appKey
func CreateWechatHmacSha256(plainText,
	appKey string) string {
	macHash := hmac.New(sha256.New, []byte(appKey))
	macHash.Write([]byte(plainText))
	return strings.ToUpper(hex.EncodeToString(macHash.Sum(nil)))
}

// CreateWeChatMd5 创建微信签名
// plainText: 待签名字符串
func CreateWeChatMd5(plainText string) string {
	md5Hash := md5.New()
	md5Hash.Write([]byte(plainText))
	return strings.ToUpper(hex.EncodeToString(md5Hash.Sum(nil)))
}

// CreateWeChatSign 创建微信签名
// signType: 签名类型
// plainText: 待签名字符串
// appKey: 微信appKey
func CreateWeChatSign(signType SignType,
	plainText, appKey string) string {
	if signType == SignTypeMd5 {
		return CreateWeChatMd5(plainText)
	}
	return CreateWechatHmacSha256(plainText, appKey)
}
